package com.card.game.ddz;

import java.util.ArrayList;

import java.util.List;
import java.util.Random;

import java.util.Vector;

import com.card.common.CardContants;
import com.card.common.MessageComm;
import com.card.game.BasePlayer;
import com.card.game.Card;
import com.card.game.CardUtils;
import com.card.game.playback.PlayBackManager;
import com.card.game.room.AbstractRoom;
import com.card.game.room.RoomState;
import com.card.message.JsonMessageCenter;
import com.card.user.UserBack;
import com.google.common.collect.Lists;
import com.xiaoao.net.common.GameConstants;
import com.xiaoao.net.json.message.JsonMessage;
import com.xiaoao.net.utils.StringUtil;
import com.xiaoao.net.utils.json.GSONUtils;

public class DdzRoom<T> extends AbstractRoom {
	protected DdzRoomInfo ddzRoomInfo;// 房间信息
	protected int curwhosTurn = -1;// 当前出牌
	protected String diZhuId;
	protected int bombNum;
	protected transient int noQiangNum;// 无人抢地主
	protected transient String lastUserId;
	protected transient DdzHand lastOutHand;
	protected transient String winUserId;
	protected transient DdzPlayBack playback;
	protected transient long curhowsTurnStartTime;

	public DdzRoom(String ownId) {
		super(CardContants.GAMETYPE_Ddz, ownId);
		this.curwhosTurn = new Random().nextInt(getMaxUserNum());
		this.ddzRoomInfo = new DdzRoomInfo();
	}

	/**
	 * 托管
	 * 
	 */
	public void autoOutCard() {
		DdzPlayer curPlayer = getPlayerByTableIndex(this.curwhosTurn);
		if (curPlayer != null) {
			Vector<Card> hand = new Vector<>();
			if (this.lastOutHand == null) {
				Card outCard = curPlayer.cards.get(curPlayer.cards.size() - 1);
				hand.add(outCard);
			}
			handOut(curPlayer, hand);
		}
	}

	// @Override
	// public void doTimedTask() {
	// super.doTimedTask();
	// if(state == RoomState.NoPeopleQiang) {
	// if(getChangeStateTime() > 2*GameConstants.SECOND) {
	// setState(RoomState.Running);
	// startGame();
	// }
	// }
	// }
	@Override
	public void doTimedTask() {
		if (state == RoomState.Ready) {
			long waitTime = System.currentTimeMillis() - this.stateChangeTime;
			if (waitTime > 2 * GameConstants.SECOND) {
				startGame();
			}
		} else if (state == RoomState.Running) {
			long waitTime = System.currentTimeMillis() - this.curhowsTurnStartTime;
			if (waitTime > 20 * GameConstants.SECOND) {
				autoOutCard();
			}
		} else if (state == RoomState.QiangDizhu) {
			long waitTime = System.currentTimeMillis() - this.curhowsTurnStartTime;
			if (waitTime > 10 * GameConstants.SECOND) {
				autoQiangDizhu();
			}
		}
	}

	private void autoQiangDizhu() {
		DdzPlayer curPlayer = getPlayerByTableIndex(this.curwhosTurn);
		if (curPlayer != null) {
			qiangDizhu(curPlayer, false, 0);
		}

	}

	@Override
	public void addPlayer(BasePlayer player) {
		synchronized (this.playerList) {
			if (this.playerList.size() < getMaxUserNum()) {
				player.setTableIndex(this.playerList.size());
				super.addPlayer(player);
				// 通知所有人房间信息改变
				sendRoomInfo();
				return;
			}
		}
	}

	public void handOut(DdzPlayer player, Vector<Card> cards) {
		DdzHand hand = new DdzHand(cards,player.cards);
		if (!hand.isRegular() || !player.isContains(cards)
				|| (hand.isPass() && (lastUserId == null || StringUtil.equals(lastUserId, player.getUserId())))
				|| (lastOutHand != null && !StringUtil.equals(this.lastUserId, player.getUserId()) && !hand.isPass()
						&& hand.compareTo(this.lastOutHand) <= 0)) {
			sendUpdateCards(player);
			broadChuPai();
			return;
		}
		if (!hand.isPass()) {
			player.removeCards(cards);
		}
		broadHandOut(player, hand);
		player.ddzInfo.setLastOutHand(hand);
		this.playback.addOutHand(player, hand);
		broadTable(null);

		if (hand.isPass()) {
			nextDoPlayer();
			return;
		}
		if (hand.isBomb()) {
			this.bombNum++;
			player.ddzInfo.addBomb();
		}
		this.lastOutHand = hand;
		this.lastUserId = player.getUserId();
		if (player.isWin()) {
			this.winUserId = player.getUserId();
			sendEnd2Player();
			endGame();
			return;
		}
		nextDoPlayer();
	}

	public void changeWhoTurn(int nextTurn) {
		this.curwhosTurn = nextTurn;
		this.curhowsTurnStartTime = System.currentTimeMillis();

	}

	public void allNotQiang() {
		changeWhoTurn(getNextPlayer());
		DdzPlayer player = getPlayerByTableIndex(this.curwhosTurn);
		this.startGame();
		// setState(RoomState.Running);
		// this.diZhuId = player.getUserId();
		// broadDiPai();
		// player.addDiPai(ddzRoomInfo.getDiPai());
		// sendUpdateCards(player);
		// broadChuPai();
		// JsonMessage message =
		// JsonMessage.createMessage(MessageComm.S2C_NoPeopleQiang);
		// broadcast(message);
		// endGame();
		// setState(RoomState.NoPeopleQiang);

	}

	// 抢地主
	ArrayList<DdzPlayer> ts = new ArrayList<>();

	// DdzPlayer [] ddz = new DdzPlayer[3];
	public void qiangDizhu(DdzPlayer player, boolean flag, int qiang) {
		if (player != null) {
			ts.add(player);
			player.qiang = qiang;
		}
		System.out.println("集合长度-------------------" + ts.size());
		System.out.println(qiang);
		System.out.println(player.qiang);
		// 不叫
		System.out.println(flag);
		// if(!flag) {
		JsonMessage message = JsonMessage.createMessage(MessageComm.S2C_DdzQiangDizhu);
		message.addProperty("userId", player.getUserId());
		message.addProperty("qiang", player.qiang);
		JsonMessageCenter.getInstance().sendMessage(message, player);
		// return;
		// }
		// JsonMessage message =
		// JsonMessage.createMessage(MessageComm.S2C_DdzQiangDizhu);
		// message.addProperty("userId", player.getUserId());
		// message.addProperty("qiang", qiang);
		broadcast(message);

		if (qiang == 3) {
			setState(RoomState.Running);
			this.playback.setDiZhuId(this.diZhuId);
			this.diZhuId = player.getUserId();
			changeWhoTurn(player.getTableIndex());
			broadDiPai();
			player.addDiPai(ddzRoomInfo.getDiPai());
			sendUpdateCards(player);
			broadChuPai();
			ts = new ArrayList<DdzPlayer>();
			return;
		} else {
			if (ts.size() == 3) {
				DdzPlayer[] arr = ts.toArray(new DdzPlayer[ts.size()]);
				for (DdzPlayer ddzPlayer : arr) {
					if (ddzPlayer.qiang == 2) {
						System.out.println("--------222------");
						setState(RoomState.Running);
						this.playback.setDiZhuId(ddzPlayer.ddzInfo.userId);
						this.diZhuId = ddzPlayer.getUserId();
						changeWhoTurn(ddzPlayer.getTableIndex());
						broadDiPai();
						ddzPlayer.addDiPai(ddzRoomInfo.getDiPai());
						sendUpdateCards(ddzPlayer);
						broadChuPai();
						ts = new ArrayList<DdzPlayer>();
						return;
					}
				}
				for (DdzPlayer ddzPlayer : arr) {
					if (ddzPlayer.qiang == 1) {
						System.out.println("--------111------");
						setState(RoomState.Running);
						this.playback.setDiZhuId(ddzPlayer.ddzInfo.userId);
						this.diZhuId = ddzPlayer.getUserId();
						changeWhoTurn(ddzPlayer.getTableIndex());
						broadDiPai();
						ddzPlayer.addDiPai(ddzRoomInfo.getDiPai());
						sendUpdateCards(ddzPlayer);
						broadChuPai();
						ts = new ArrayList<DdzPlayer>();
						return;
					}
				}
				if (arr[0].qiang == 0 && arr[1].qiang == 0 && arr[2].qiang == 0) {
					ts = new ArrayList<DdzPlayer>();
					allNotQiang();
					return;
				}
			}
			// System.out.println(arr[arr.length-1]);
			// setState(RoomState.Running);
			// this.playback.setDiZhuId(arr[arr.length-1].ddzInfo.userId);
			// this.diZhuId = arr[arr.length-1].getUserId();
			// changeWhoTurn(arr[arr.length-1].getTableIndex());
			// broadDiPai();
			// arr[arr.length-1].addDiPai(ddzRoomInfo.getDiPai());
			// sendUpdateCards(arr[arr.length-1]);
			// broadChuPai();
		}
		// noQiangNum++;
		// if(noQiangNum == 3) {
		// allNotQiang();
		// return;
		// }
		nextDoPlayer();
		// }

	}

	// 无人抢开始下局
	public void nextDoPlayer() {
		changeWhoTurn(getNextPlayer());
		if (!StringUtil.NullOrEmpty(this.lastUserId)) {
			DdzPlayer player = getPlayerByTableIndex(this.curwhosTurn);
			if (StringUtil.equals(this.lastUserId, player.getUserId())) {
				this.lastUserId = null;
				this.lastOutHand = null;
			}
		}
		broadChuPai();
	}

	// 解散房间
	@Override

	public void disbandRoom() {
		if (isStartGame) {
			calAllGame(true);
		} else {
			JsonMessage message = JsonMessage.createMessage(MessageComm.S2C_RoomDisband);
			message.addProperty("firstId", ownerId);
			broadcast(message);
			clearRoom();
		}
	}

	@Override
	public void disbandAgencyRoom() {
		if (isStartGame) {
			calAllGame(true);
		} else {
			JsonMessage message = JsonMessage.createMessage(MessageComm.S2C_DisbandAgencyCreateRoom);
			message.addProperty("firstId", ownerId);
			broadcast(message);
			clearRoom();
		}
	}

	public void clearData() {
		this.noQiangNum = 0;
		this.diZhuId = null;
		setState(RoomState.End);
	}

	public void sendEnd2Player() {
		boolean isDzWin = StringUtil.equals(this.diZhuId, this.winUserId);
		int bombNum = Math.min(this.bombNum, getMaxBomb());
		boolean isChunTian = isDzWin ? isNMChunTian() : getPlayerById(this.diZhuId).ddzInfo.getOutSize() <= 1;
		int score = (int) Math.pow(2, bombNum);
		if (isChunTian)
			score *= 2;
		List<DdzResult> resultList = Lists.newArrayList();

		UserBack ub = new UserBack(this);
		for (int i = this.playerList.size() - 1; i >= 0; i--) {
			DdzPlayer player = (DdzPlayer) playerList.get(i);
			int tempScore = score;
			if (isDiZhu(player.getUserId())) {
				tempScore = isDzWin ? score * 2 : -score * 2;
			} else {
				tempScore = isDzWin ? -score : score;
			}
			player.ddzInfo.calGame(tempScore);
			DdzResult result = new DdzResult(player, tempScore);
			resultList.add(result);
			ub.addScore(player.nickName, tempScore);
		}

		JsonMessage message = JsonMessage.createMessage(MessageComm.S2C_Ddz_GAME_END);
		message.addProperty("results", resultList);
		message.addProperty("playNum", playNum);
		message.addProperty("isDzWin", isDzWin);
		message.addProperty("isChunTian", isChunTian);
		message.addProperty("bombNum", this.bombNum);
		message.addProperty("curBei", (int) Math.pow(2, bombNum));
		message.addProperty("lastOutUserId", this.lastUserId);
		message.addProperty("lastOutCard", this.lastOutHand);
		broadcast(message);
		if (!isMatchRoom()) {
			this.playback.setResultList(resultList);
			this.playback.setDiZhuId(diZhuId);
			this.playback.setDiPai(Lists.newArrayList(ddzRoomInfo.getDiPai()));
			PlayBackManager.getInstance().savePlayback(playback, this, ub);
		}
	}

	public DdzPlayer getPlayerById(String userId) {
		return (DdzPlayer) super.getPlayerById(userId);
	}

	public DdzPlayer getPlayerByTableIndex(int index) {
		return (DdzPlayer) super.getPlayerByTableIndex(index);
	}

	public boolean isEndGame() {
		return this.playNum >= roomSetting.getMaxPlayNum();
	}

	@Override
	public void endGame() {
		super.endGame();
		DdzPlayer winPlayer = getPlayerById(this.winUserId);
		this.curwhosTurn = winPlayer.getTableIndex();
		this.bombNum = 0;
		this.diZhuId = null;
		this.lastUserId = null;
		this.lastOutHand = null;
		this.winUserId = null;
		clearData();
		if (isEndGame()) {
			calAllGame(false);
			return;
		}
	}

	public void calAllGame(boolean isDisband) {
		List<DdzAllResult> resultList = Lists.newArrayList();
		for (int i = this.playerList.size() - 1; i >= 0; i--) {
			DdzPlayer player = (DdzPlayer) playerList.get(i);
			resultList.add(new DdzAllResult(player, this.playNum));
		}
		JsonMessage message = JsonMessage.createMessage(MessageComm.S2C_Ddz_ALL_END);
		message.addProperty("resultList", resultList);
		if (isDisband) {
			message.addProperty("isDisband", 1);
		}
		broadcast(message);
		clearRoom();
	}

	public void broadHandOut(DdzPlayer player, DdzHand hand) {
		JsonMessage message = JsonMessage.createMessage(MessageComm.S2C_DdzHandOut);
		message.addProperty("userId", player.getUserId());
		message.addProperty("handSize", player.getHandSize());
		message.addProperty("outHand", hand);
		broadcast(message);
	}

	public void broadTable(BasePlayer temp) {
		List<DdzInfo> ddzInfoList = Lists.newArrayList();
		for (BasePlayer p : getPlayerList()) {
			DdzPlayer player = (DdzPlayer) p;
			ddzInfoList.add(player.ddzInfo);
		}
		JsonMessage message = JsonMessage.createMessage(MessageComm.S2C_DdzTable);
		message.addProperty("ddzInfoList", ddzInfoList);
		message.addProperty("curBei", (int) Math.pow(2, this.bombNum));
		if (temp != null) {
			JsonMessageCenter.getInstance().sendMessage(message, temp);
		} else {
			broadcast(message);
		}
	}

	public void broadChuPai() {
		broadChuPai(null);
	}

	public void broadChuPai(BasePlayer temp) {
		JsonMessage message = JsonMessage.createMessage(MessageComm.S2C_ChuPai);
		message.addProperty("curwhosTurn", curwhosTurn);
		if (state == RoomState.QiangDizhu) {
			message.addProperty("isQiang", true);
		} else {
			message.addProperty("isQiang", false);
			message.addProperty("lastUserId", lastUserId);
			message.addProperty("lastOutHand", lastOutHand);
		}
		if (temp != null) {
			JsonMessageCenter.getInstance().sendMessage(message, temp);
		} else {
			broadcast(message);
		}
	}

	public void broadDiPai() {
		JsonMessage message = JsonMessage.createMessage(MessageComm.S2C_DdzDiPai);
		message.addProperty("diPai", ddzRoomInfo.getDiPai());
		message.addProperty("diZhuId", this.diZhuId);
		message.addProperty("curwhosTurn", curwhosTurn);
		broadcast(message);
	}

	@Override
	public void startGame() {
		this.playNum++;
		super.startGame();
		setState(RoomState.QiangDizhu);
		Vector<Card> tableCards = CardUtils.createDdz();
		Vector<Card> diPai = CardUtils.faPaiToVector(tableCards, 3);
		System.err.println("===========开始游戏:" + tableCards.size() + "===================");
		this.ddzRoomInfo.setDiPai(diPai);
		System.err.println("===========底牌:" + GSONUtils.ToJSONString(diPai) + "===================");
		for (int i = 0; i < playerList.size(); i++) {
			DdzPlayer player = (DdzPlayer) playerList.get(i);
			Vector<Card> outCard = CardUtils.faPaiToVector(tableCards, 17);
			player.initCards(outCard);
			System.err.println("===========发牌:" + player.getHandSize() + "===================");
			sendStartGame(player);
		}
		System.err.println("===========开始游戏完毕:" + tableCards.size() + "===================");
		this.playback = new DdzPlayBack(this);
		this.curhowsTurnStartTime = System.currentTimeMillis();

		broadChuPai();
	}

	public void sendUpdateCards(DdzPlayer player) {
		JsonMessage message = new JsonMessage(MessageComm.S2C_HandUpdate2Out);
		message.addProperty("hand", player.cards);
		message.addProperty("curwhosTurn", curwhosTurn);
		JsonMessageCenter.getInstance().sendMessage(message, player);
	}

	public void sendStartGame(DdzPlayer player) {
		JsonMessage message = new JsonMessage(MessageComm.S2C_StartGame);
		message.addProperty("hand", player.cards);
		JsonMessageCenter.getInstance().sendMessage(message, player);
	}

	public int getNextPlayer() {
		return curwhosTurn == getMaxUserNum() - 1 ? 0 : curwhosTurn + 1;
	}

	@Override
	public int getMaxUserNum() {
		return 3;
	}

	public int getMaxBomb() {
		return Integer.MAX_VALUE;
	}

	public boolean isDiZhu(String userId) {
		return StringUtil.equals(this.diZhuId, userId);
	}

	public boolean isNMChunTian() {
		for (BasePlayer basePlayer : playerList) {
			DdzPlayer p = (DdzPlayer) basePlayer;
			if (!StringUtil.equals(diZhuId, p.getUserId())) {
				if (p.ddzInfo.getOutSize() > 0)
					return false;
			}
		}
		return true;
	}

	@Override
	public void breakConnect(BasePlayer p) {
		DdzPlayer player = (DdzPlayer) p;
		JsonMessage message1 = new JsonMessage(MessageComm.C2S_BreakConnect);
		message1.addProperty("room", this);
		JsonMessageCenter.getInstance().sendMessage(message1, player);
		if (isStartGame) {
			sendUpdateCards(player);
			broadTable(player);
			broadChuPai(player);
			if (this.state == RoomState.DisbandRequest) {
				sendDisandRoomRequest();
			}
		}
		player.changeOnline(true);
	}

	public static void main(String[] args) {
		System.err.println((int) Math.pow(2, 3));
	}
}
